package com.huanghuai.retail.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huanghuai.retail.common.R;
import com.huanghuai.retail.dto.InformationDto;
import com.huanghuai.retail.dto.InformationTypeDto;
import com.huanghuai.retail.dto.TypeNumberDto;
import com.huanghuai.retail.entity.PInformation;
import com.huanghuai.retail.entity.PType;
import com.huanghuai.retail.entity.SInventory;
import com.huanghuai.retail.entity.Storage;
import com.huanghuai.retail.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/information")
public class InformationController {

    @Autowired
    private InformationService informationService;

    @Autowired
    private TypeService typeService;

    @Autowired
    private BrandService brandService;

    @Autowired
    private BrandTypeService brandTypeService;

    @Autowired
    private SInventoryService sInventoryService;

    @Autowired
    private StorageService storageService;


    /**
     * 根据id查询一条商品信息，并封装到dto中, 这个操作主要用于修改时显示信息
     * @param id
     * @return
     */
    @GetMapping("find/{id}")
    public R<InformationDto> findById(@PathVariable Long id){
        PInformation information = informationService.getById(id);
        if (information == null)
            return R.error("查询数据失败");

        InformationDto informationDto = informationService.disposeDto(information);

        return R.success(informationDto);
    }

    /**
     * 查询操作
     * 根据条件查询商品并进行分页查询
     *
     *  问题：有一组type或brand的ids如何进行查询对应信息
     *  解决：使用lambdaQueryWrapper.in 传入参数与eq一样，只是最后一个参数变成了数组
     *
     *     注意：in操作中数组不能为空，我传了以后-1，使他不为空
     * @param page
     * @param pageSize
     * @param name
     * @param type
     * @param brand
     * @param warp
     * @return
     */
    @GetMapping("page")
    public R<Page> findByCondition(@RequestParam(defaultValue = "1")int page,
                                   @RequestParam(defaultValue = "10")int pageSize,
                                   String name, String type, String brand, String warp){

        //分页构造器
        Page<PInformation> pageInfo = new Page<>(page, pageSize);

        LambdaQueryWrapper<PInformation> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        //处理warp，直接模糊查询
        lambdaQueryWrapper.like(warp!=null, PInformation::getWrap, warp);

        //处理name，直接模糊查询
        lambdaQueryWrapper.like(name!=null, PInformation::getName, name);

        //处理type，先模糊查询获取type的id，再进行in查询
        List<Long> typeIds = null;
        if (type != null)
            typeIds = typeService.getIdsByName(type);
        if (typeIds != null && typeIds.size() == 0)
            typeIds.add(-1L);
        lambdaQueryWrapper.in(typeIds!=null, PInformation::getTypeId, typeIds);

        //处理brand，先模糊查询获取brand的id，再进行in查询
        List<Long> brandIds = null;
        if (brand != null)
            brandIds = brandService.getIdsByName(brand);
        if (brandIds != null && brandIds.size() == 0)
            brandIds.add(-1L);
        lambdaQueryWrapper.in(brandIds!=null,PInformation::getBrandId, brandIds);

        //执行分页查询
        informationService.page(pageInfo,lambdaQueryWrapper);

        //查询商品信息
        List<PInformation> list = pageInfo.getRecords();
        if (list.size() == 0)
            return R.error("未查询到信息");

        //封装成dto信息到Page中
        List<InformationDto> listDto = new ArrayList<>();
        Page<InformationDto> informationDtoPage = new Page<>();
        BeanUtils.copyProperties(pageInfo, informationDtoPage, "records");
        for (int i = 0; i < list.size(); i ++)
            listDto.add(informationService.disposeDto(list.get(i)));
        informationDtoPage.setRecords(listDto);

        return R.success(informationDtoPage);
    }


    /**
     * 新增时时间出了问题，这个问题在火车票里出现过，但不知道为啥当时解决了。
     *  已经解决， 实体类数据类型应该为LocalDateTime
     *
     *  疑问：前端新增时对于工厂、品牌信息肯定是传入查到的具体名称，而非id，应该怎么解决。
     *      前端解决
     *
     *  问题： 1、图片的上传和下载问题
     *          解决：编写了controller类写了下载与展示图片的方法，下载时返回路径名称，存入数据库，
     *              上传时，根据路径名称将图片展示到前端
     * @param information
     * @return
     */
    @PostMapping("add")
    public R<String> addInformation(@RequestBody PInformation information){

        if (!informationService.pdInformation(information))
            return R.error("传入信息不全或错误");
        //保存商品
        informationService.save(information);
        //维护品牌类别表
        informationService.maintenance(information);
        return R.success("保存成功");
    }

    /**
     * 修改操作，有一些问题，因为前端展示的其实是Dto，那么修改的是Dto中特有的信息而非实体类中的信息
     *  那么穿过来的数据虽然可以用实体类接收，但是修改Dto特有信息应该怎么对应到实体类中的信息呢？
     *      疑问：是前端页面做了绑定？(修改Dto中特有数据时，同时修改传回来实体类对应的信息)
     *           后端接收Dto数据，再根据Dto中特有数据进行查询塞入实体类中进行修改？
     *     前端解决
     *
     *  问题：1、对于brandType的中间表维护，不应该先删除再新增
     * @param information
     * @return
     */
    @PutMapping("update")
    public R<String> updateInformation(@RequestBody PInformation information){

        if (informationService.pdInformation(information))
            return R.error("修改失败");
        //判断是否删除之前已有中间表信息
        informationService.pdDelBrandType(information);

        //修改并维护商品类别信息
        informationService.maintenance(information);

        informationService.updateById(information);
        return R.success("修改成功");
    }


    /**
     * 出入库明细
     * @param informationDto
     * @param shopId
     * @return
     */
    @GetMapping("/findPoGoods")
    public R<InformationDto> findPoGoods(InformationDto informationDto,Long shopId,Integer storageId) {
        if(shopId==null&&storageId==null){
            return R.error("暂无数据");
        }else if(shopId!=null){
            PInformation pInformation = informationService.getById(shopId);
            if(pInformation==null){
                return R.error("查询商品信息不存在,请重新选择");
            }
            BeanUtils.copyProperties(pInformation, informationDto);
            PType pType = typeService.getById(pInformation.getTypeId());
            informationDto.setTypeName(pType.getNameTwo());
            if(storageId==null){
                return R.success(informationDto);
            }
            else {
                LambdaQueryWrapper<SInventory> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(SInventory::getProductId,shopId).eq(SInventory::getStorageId,storageId);
                SInventory sInventory = sInventoryService.getOne(queryWrapper);
                informationDto.setInventoryNumber(sInventory.getNumber());
            }
        }
        return R.success(informationDto);

    }

    /**
     *货品列表
     * @param
     * @return
     */
    @GetMapping("/findShops")
    public R<Page> findShops( @RequestParam(defaultValue = "1") Integer page,
                              @RequestParam(defaultValue = "10") Integer pageSize,
                              @RequestParam(required = false) List<Integer> shopTypeId,
                              @RequestParam(required = false) List<Integer> shopId,
                              @RequestParam(required = false) List<String> shopName,
                              @RequestParam(required = false) List<String> specs,
                              @RequestParam(required = false) List<Integer> storageId
    ){
        return informationService.getShopsPage(page,pageSize,shopId,shopTypeId,shopName,specs,storageId);
    }
    @GetMapping("/findIds")
    public R<List> findIds(){
        LambdaQueryWrapper<PInformation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(PInformation::getId, PInformation::getName);
        List<PInformation> list = informationService.list(queryWrapper);
        if (list.isEmpty()){
            return R.error("暂无信息!");
        }
        return R.success(list);
    }
    @GetMapping("/findTypes")
    public R<List> findTypes(){
        List<PType> list = typeService.list();
        if (list.isEmpty()){
            return R.error("暂无信息!");
        }
        return R.success(list);
    }

    /**
     * 扇形统计图
     * @return
     */

    @RequestMapping("/pieChart")
    public R<List> TypePercent(){

        List<InformationTypeDto> pieChart = new ArrayList<>();

        List<Storage> list = storageService.list();

        for (Storage storageIds : list){
            InformationTypeDto informationTypeDto = new InformationTypeDto();

            Long storageId = storageIds.getId();

            if (storageId == null){
                break;
            }

            String storageName = storageIds.getStorageName();
/*            int total = sInventoryService.getNumsByStorageId(storageId);
            if (total == 0){
                break;
            }*/

            List<PType> typeList = typeService.list();
            if (typeList == null){
                return R.error("没有类型");
            }

            List<Object> types = new ArrayList<>();

            for(PType type : typeList){

                TypeNumberDto typeNumberDto = new TypeNumberDto();

                int number = 0;

                if(type == null){
                    break;
                }
                String tName = type.getNameTwo();
                Long typeId = type.getId();
                List<PInformation> productIds = informationService.getIdByTypeId(typeId);
                for (PInformation proId : productIds){
                    if (proId == null){
                        break;
                    }
                    Long productId = proId.getId();

                    Long storageId2= sInventoryService.getStorageIdByProductId(productId,storageId);
                    if (storageId2 == null){
                        break;
                    }

                    int num = sInventoryService.getNumByProductId(productId,storageId);
                    if (num == 0){
                        break;
                    }
                    number += num;
                }
/*              double doubleValue  = (double)number / total;
                BigDecimal bg = new BigDecimal(doubleValue);
                //将小数保留4位，并且四舍五入
                double i = bg.setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
                //判断i是不是>1,大于1换成%分数就超100了
                if(i>=1){
                    i=1.00;
                }
                //设置格式保留两位小数
                DecimalFormat df = new DecimalFormat("0.00%");*/

                //informationTypeDto.setTypePercent(df.format(i));
                typeNumberDto.setName(tName);
                typeNumberDto.setNumber(number);
                types.add(typeNumberDto);
                //informationTypeDto.setTotal(total);
            }
            informationTypeDto.setType(types);
            informationTypeDto.setName(storageName);
            pieChart.add(informationTypeDto);
        }
        return R.success(pieChart);
    }

}
